package team3;

/**A Goodness function that treats Edges and Corners as more valuable then
 * center peices.
 * <p>
 * This function, slightly stolen from
 * <a href="http://en.wikipedia.org/wiki/Reversi">The Fountain of Knowledge</a>,
 * treats 'central' edge peices as move valuable then the center of the board,
 * corners as more valuable then edges, and edges near corners as being costly
 * (worth less then center peices), if the corner is unfilled. This last portion
 * of the goodness function is because being next to an unfilled corner almost
 * gaurantees the loss of the corner.
 */
public class WeightedBoardControlGoodness implements GoodnessFunction
{
    /**Determines the weighted goodness, of the given <code>state</code>
     * @param state The state to evaluate
     * @param playerToMaximize The player to maximize
     * @return A value near 0 to 1... such that 1 is better for the player.
     */
    public double evaluateGoodness(BoardState state, AI.Player playerToMaximize)
    {
        AI.Player[][] board = state.getState();
        double blackCount = 0;
        double whiteCount = 0;
        int totalCount = 0;
        for (int row = 0; row < 8; row++)
        {
            for (int col = 0; col < 8; col ++)
            {
                if(board[row][col]==AI.Player.EMPTY)
                    continue;
                totalCount++;
                int weight = getWeight(row, col, board);
                if (board[row][col] == AI.Player.BLACK)
                    blackCount += weight;
                else
                    whiteCount += weight;
            }
        }
        if(playerToMaximize == AI.Player.BLACK)
            return blackCount / totalCount;
        return whiteCount / totalCount;
    }

    /**Determines the weight for a given location, with the baord state
     * @param row Row of peice to calculate weight for
     * @param col Col of peice to calculate weight for
     * @param board State of the board
     * @return Weight of the location
     */
    private int getWeight(int row, int col, AI.Player[][] board)
    {
        if ((row == 0 || row == 7) && (col == 0 || col == 7))
            return 8;
        if (isAdjacentToCorner(row, col) && cornerUnfilled(row, col, board))
            return -8;
        if ((row == 0 || row == 7) || (col == 0 || col == 7))
            return 2;
        return 1;
    }

    /**Determines if a location is within one square of a corner
     * @param row Row of the location
     * @param col Column of the location
     * @param state S
     * @return true if the location is a corner, or a square within one jump of a corner. False otherwise.
     */
    private boolean isAdjacentToCorner(int row, int col)
    {
        if(row<=1&&col<=1)
            return true;
        if(row<=1&&col>=6)
            return true;
        if(row>=6&&col<=1)
            return true;
        if(row>=6&&col>=6)
            return true;
        return false;
    }

    /**Determines if the corner next to the location at row,col is unfilled.
     * @param row Row of location next to a corner
     * @param col Column of location next to a corner
     * @param state State of the game
     * @return true if the closest corner is empty, false if otherwise
     */
    private boolean cornerUnfilled(int row, int col, AI.Player[][] state)
    {
        //determine closest corner;
        //ex. if at 6,1; row-4=2, col-4=-3, corner at: row=7, col=0
        if(row-4 < 0) row=0;
        else row=7;
        if(col-4<0) col=0;
        else col=7;

        return state[row][col]==AI.Player.EMPTY;
    }

	public String getName()
	{
		return "edge weighted board control";
	}
}

